/*
 * Copyright 2007 National Bioinformatics Network
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package dgbgui.gui;

import java.util.HashSet;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import dgbgui.gui.widgets.WidgetStore;
import dgbgui.gui.widgets.visual.QueryWidget;
import dgbgui.gui.widgets.visual.results.ResultWidget;
import dgbgui.modeldocument.Query;
import dgbgui.modeldocument.primitives.Primitive;
import edu.umd.cs.piccolo.PCanvas;
import edu.umd.cs.piccolo.PLayer;
import edu.umd.cs.piccolo.PNode;

public abstract class GraphicsScene extends Observable implements Observer {
    
    public GraphicsScene() {
        // Do it like this to create the correct structures for piccolo
        // Observed that some updating doesn't occur correctly if the
        // layer etc are created manually.
        PCanvas newCanvas = new PCanvas();
        
        m_layer = newCanvas.getLayer();
    }
    
    /**
     * @return the layer node of the graphics scene
     */
    public PLayer getLayer() {
        assert ( m_layer instanceof PLayer );
        return (PLayer)m_layer;
    }
    
    public void queriesSelected(Set<Query> queries) {
        for ( Query query : queries ) {
            // Default widgets
            Set<QueryWidget> defaultWidgets = WidgetStore.getInstance().getWidgets(query);
            for ( QueryWidget widget : defaultWidgets ) {
                widget.highlight();
            }
        }
        setChanged();
        notifyObservers();        
    }
    
    public void queriesDeselected(Set<Query> queries) {
        for ( Query query : queries ) {
            // Deafult widgets
            Set<QueryWidget> defaultWidgets = WidgetStore.getInstance().getWidgets(query);
            for ( QueryWidget widget : defaultWidgets ) {
                widget.unhighlight();
            }
        }
        setChanged();
        notifyObservers();
    } 
    
    public void highlightResult(Set<Object> selection) {
        for ( Object obj : selection ) {
            if ( obj instanceof Primitive ) {
                Set<ResultWidget> widgets = WidgetStore.getInstance().getWidgets((Primitive)obj);
                for ( ResultWidget widget : widgets ) {
                    widget.highlight();
                }
            }
        }
        setChanged();
        notifyObservers();
    }
    
    public void unhighlightResult(Set<Object> selection) {
        for ( Object obj : selection ) {
            if ( obj instanceof Primitive ) {
                Set<ResultWidget> widgets = WidgetStore.getInstance().getWidgets((Primitive)obj);
                for ( ResultWidget widget : widgets ) {
                    widget.unhighlight();
                }
            }
        }
        setChanged();
        notifyObservers();
    }
    
    public void showActivePrimitive(Primitive primitive) {
        Set<ResultWidget> widgets = WidgetStore.getInstance().getWidgets(primitive);
        for ( ResultWidget w : widgets ) {
            w.showFrom();
        }
    }
    
    public void restoreActivePrimitive(Primitive primitive) {
        Set<ResultWidget> widgets = WidgetStore.getInstance().getWidgets(primitive);
        for ( ResultWidget w : widgets ) {
            w.restoreFrom();
        }
    }
    
    public void showSelectablePrimitives(Set<Primitive> primitives) {
        Set<ResultWidget> widgets = new HashSet<ResultWidget>();
        for ( Primitive primitive : primitives) {
            widgets.addAll(WidgetStore.getInstance().getWidgets(primitive));
        }
        
        for ( ResultWidget w : widgets ) {
            w.showSelectable();
        }
    }
    
    public void restoreSelectablePrimitives(Set<Primitive> primitives) {
        Set<ResultWidget> widgets = new HashSet<ResultWidget>();
        for ( Primitive primitive : primitives) {
            widgets.addAll(WidgetStore.getInstance().getWidgets(primitive));
        }
        
        for ( ResultWidget w : widgets ) {
            w.restoreSelectable();
        }
    }
    
    // ---------- Fields ----------
    
    // The layer node containing the visual nodes.
    // Diferent cameras can be attached to this node 
    // for different vies.
    protected PNode m_layer;

}
